package com.woniu.interceptor;

import com.alibaba.fastjson.JSON;
import com.woniu.util.JwtUtil;
import com.woniu.util.ResponseData;
import com.woniu.util.ResponseEnum;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 校验用户登录状态的拦截器
 * 1.实现HandlerInterceptor，放入容器，并且重写preHandle方法
 * 2.注册主机的拦截器(在springmvc的配置类中注册)
* */
@Component                 // 类注册到容器中
public class LoginInterceptor implements HandlerInterceptor {
    // 操作redis的工具类，采用了key-value方式存储到数据库
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 在Controller之前
     * 1.获取前端请求头中的jwt
     *    没带：拦截
     *    带了：2步
     * 2.用系统的密钥解密
     *    解不开：拦截
     *    解开：3步
     * 3.拿前端的jwt和redis的jwt做对比       前端JWT == redis的JWT
     *    对比不成功(redis的jwt过期了)：拦截
     *    成功：4步
     * 4.给jwt续期
    * */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1.获取前端请求头中的jwt
        String headerJWT = request.getHeader("authentication");
        response.setContentType("application/json; charset=utf-8");

        if (headerJWT == null) {
            // 响应未登录的标识
            String jsonString = JSON.toJSONString(ResponseData.fail(ResponseEnum.NO_LOGIN));
            // 直接打印对象不写，得转json
            response.getWriter().print(jsonString);
            return false;       // 拦截
        }

        // 2.用系统密钥解密
        if (!JwtUtil.deCode(headerJWT)) {
            // 响应未登录得标识
            String jsonString = JSON.toJSONString(ResponseData.fail(ResponseEnum.NO_LOGIN));
            // 直接打印对象不行，得转json
            response.getWriter().print(jsonString);
            return false;
        }

        // 3.拿前端的jwt和redis的jwt做对比

        // 从JWT中的用户信息
        Map userMap = JwtUtil.getJwtUser(headerJWT);
        //Long employeeId = (Long)userMap.get("employeeId");
        Long employeeIdTemp = (Long) userMap.get("employeeId");
        Integer employeeId = Integer.parseInt(String.valueOf(employeeIdTemp));
        String redisJWT = stringRedisTemplate.opsForValue().get("JWT:" + employeeId);
        if (!headerJWT.equals(redisJWT)) {
            // 响应未登录的标识
            String jsonString = JSON.toJSONString(ResponseData.fail(ResponseEnum.NO_LOGIN));
            // 直接打印对象不行，得转json
            response.getWriter().print(jsonString);
            return false;
        }

        // 4.对jwt续期
        stringRedisTemplate.expire("JWT:" + employeeId, 20, TimeUnit.MINUTES);  // 给指定key加时间
//        System.out.println("进入拦截器");
        return true;    // 放行
    }
}
